Function CosmToolboxIsLoaded {
	$MyPath=$MyInvocation.MyCommand.Path
	$myProgram=$MyInvocation.mycommand.Name
	$MyFolder=[System.IO.Path]::GetDirectoryName($Mypath)
	write-host "$myProgram loaded from $MyFolder" (get-Date) -ForegroundColor Green 
	returm $True
}
Function WebClient ($baseaddress="") {
	$local:WC = new-object System.Net.WebClient #make sure we don't pick up a more global object called WC
	$WC.Headers.Add("user-agent", "PowerShell User")
	$WC.baseAddress = $baseaddress
	
	Return $WC 
}

function MakeRegExp ([Hashtable]$parms) {
<#
.SYNOPSIS
	Utility to create a regular expression that will match a value to  one of a set of strings. 
	The matched value may be abbreviated to the minimum level necessary to distinguish them.
.PARAMETER
	Parameter parms is a hashtable that contains as keys, the list of strings to be matched. 
	The associated value is the minimum length of of a string to be considered a matched value.
.DESCRIPTION
	The returned regular expression is built up of a regex fragment for each key. The fragment
	is named the same as the complete key so that the key which  was matched is known
.EXAMPLE
	$regexp = MakeRegExp  @{fred=2;sam=1} #returns  \A(?<fred>fr(?:e(?:d)?)?)|(?<sam>s(?:a(?:m)?)?)\Z
	if ("fre" -match $regexp) then # returns true
#>
	$RegExpArray=@() #an array to hold the rxFrag fragment for each key
	#As we build the fragment we use * as an insertion point for following parts
	foreach ($key in $parms.keys) { #E.g. @{fred=2;sam=1}
		# find the shortest string that will be considered a match
		$MinKey=$key.substring(0,$parms[$key]) #E.g. for "fred=2" MinKey=fr
		#give the match a name for the complete string
		[string]$rxFrag = "(?<" + $key + ">" + $MinKey + "*)" 	#E.g. (?<fred>fr*)
		$keylen=$key.length
		for ($i=$parms[$key];$i -lt $keylen ;$i++){ #add each additional letter as optional
			[string]$char="(?:" + $key.chars($i) + "*)?" # e.g.  (?:e*)?  and (?:d*)?
			# * is  new insertion point ?: stops this being a separate match
			$y=$rxFrag.LastIndexOf("*")
			$rxFrag=$rxFrag.insert( $y, $char)  #E.g. (?<fred>fr(?:e*)?*) and  (?<fred>fr(?:e(?:d*)?*)?)
			# remove previous insertion point
			$rxFrag=$rxFrag.remove($rxFrag.LastIndexOf("*"),1)   #E.g. (?<fred>fr(?:e*)?) and  (?<fred>fr(?:e(?:d*)?)?)
		}
		# remove last insertion point
		$rxFrag=$rxFrag.remove($rxFrag.LastIndexOf("*"),1)    #E.g. (?<fred>fr(?:e(?:d)?)?)

		$RegExpArray += $rxFrag
	}
	# anchor to start and end of string
	$regexp="\A" + [string]::join("|",$RegExpArray)  + "\Z" #E.g. \A(?<fred>fr(?:e(?:d)?)?)|(?<sam>s(?:a(?:m)?)?)\Z
	Return $regexp
}

Function Convert_CSVDatapointToHT {
	<#
	.Synopsis
		Takes a CSV string containing a Cosm datapoint, converts to a Dictionary object (hashtable) and puts it back into the pipeline
	#>
	param(
		[Parameter(Mandatory=$true,Position=0)]$feed
		,[Parameter(ValuefromPipeline=$True,Mandatory=$true,Position=1)]$DatapointCSV
	)
	Begin {
		Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started" 
	}
	Process {	
		Write-Verbose "$($MyInvocation.MyCommand.Name):: Process started"
		#$DatapointHT=@{}
		Try {
			#-debug [string]$DatapointCSV #debug
			$val = $DatapointCSV -split ","
			[Hashtable]$DatapointHT = @{feed = $feed; stream= $val[0]; timestamp = get-date $val[1]; value = $val[2]} 
			#write-Host $DatapointHT.keys 
			#write-host $datapointHT[$DataPointHT.keys] #debug
		}
		Catch {
			Throw "$($MyInvocation.MyCommand.Name):: Unknown Problem"
		}
		Finally {
			write-Output $DatapointHT # Add to pipeline	
		}
	}
	End {
		Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"
	} 
}

Function Prorate_Datapoints {
	param (
		[Parameter(ValuefromPipeline=$False,Mandatory=$true,Position=0)]$Prorate_Rules
		,[Parameter(ValuefromPipeline=$True,Mandatory=$true,Position=1)][Hashtable]$Datapoint
	)
	Begin {
		Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started" 
		$x=[decimal[]]$Prorate_Rules.x
		$y=[decimal[]]$Prorate_Rules.y 
		# there must be a y for each x and x's must be in sequential order
		if ($x.count -ne $y.count) {Throw "Unequal number of lookup values"}
		For ($i=0; $i -lt $x.count-1; $i++) {
			if ($x[$i] -lt $x[$i+1]) {continue}
			else {throw "lookup values must be unique and ordered seqential"}
		}
	}
	process {	Write-Verbose "$($MyInvocation.MyCommand.Name):: Process started"
		$value = [decimal]$datapoint.value
		Try {
			# find the largest x lower than value
			:findRange for ($i = 0; $i -lt $x.count-1; $i++) {
				$x_lo=$x[$i]
				$x_hi=$x[$i+1]
				$x_diff=$x_hi - $x_lo
				$y_lo=$y[$i]
				$y_hi=$y[$i+1]
				$y_diff=$y_hi - $y_lo
				write-debug "x_lo=$x_lo x_diff=$x_diff  y_lo=$y_lo y_diff=$y_diff"
				Switch ($value) {
					{$_ -le $x_lo} {$newValue=$y_lo ; break findRange}
					{$_ -ge $x_hi} {$newValue=$y_hi ; continue findRange}
					default {$Newvalue = $y_diff / $x_diff * ($_ - $x_lo) + $y_lo ; break findRange}
				}
			}
			write-debug "input:$value Output:$newValue"
			$out=$datapoint.clone()
			$out.value=$newValue
			write-Output $out
		}
		Catch {
			Throw "$($MyInvocation.MyCommand.Name):: Unknown Problem"
		}
	}
	End {
		Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"
	}
}

function List_HashTable {
	param (
		[Parameter(ValuefromPipeline=$true,Mandatory=$true,Position=0)]$HT
	)
	End { 
		foreach ($key in $($HT.keys)) {
			write-Host "&$key=$($HT[$key])" -NoNewline -separator "&"
		}
	}
}

filter isNumeric() {
	return $_ -is [byte]  -or $_ -is [int16]  -or $_ -is [int32]  -or $_ -is [int64]  `
	   -or $_ -is [sbyte] -or $_ -is [uint16] -or $_ -is [uint32] -or $_ -is [uint64] `
	   -or $_ -is [float] -or $_ -is [double] -or $_ -is [decimal]
}		

Function URLEncode ($in){
	<#
	URLencode replaces (+ by %2B) (: by %3A) (% by %25) (; by %3B) (, by %2C)  (\ by %5C)
	PN: This is incomplete and unused. as a bypass all ISO8601 times are sent as UTC 
	#>
	$out=$in -replace '[+]', '%2B'
	return $out
}

